package com.slipper.config;

import com.slipper.common.service.CommonService;
import com.slipper.system.backup.bo.BackupBO;
import com.slipper.system.backup.service.BackupRestoreService;
import com.slipper.system.backup.service.QuartzRestoreService;
import com.slipper.system.restore.bo.RestoreBO;
import com.slipper.system.restore.service.RestoreService;
import com.slipper.system.version.properties.VersionProperties;
import com.slipper.util.DatabaseUtil;
import com.slipper.util.Tool;
import com.slipper.util.UUID;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.ClassPathResource;

import javax.sql.DataSource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Configuration
@DependsOn("backupRestoreService")
public class DatabaseInitConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(DatabaseInitConfiguration.class);

    @Resource
    private VersionProperties versionProperties;
    @Resource
    private DataSource dataSource;
    @Resource
    private CommonService commonService;
    @Resource
    private RestoreService restoreService;
    @Resource
    private BackupRestoreService backupRestoreService;
    @Resource
    private QuartzRestoreService quartzRestoreService;

    @PostConstruct
    public void checkAndInitDatabase() throws Exception {
        try (Connection conn = dataSource.getConnection()) {
            DatabaseUtil.setType(conn.getMetaData().getDatabaseProductName());

            List<Map<String, Object>> dataList = commonService.queryList("select * from sys_version");

            String id = null;
            String branch = null;
            String branchVersion = null;
            if (dataList != null && !dataList.isEmpty()) {
                Map<String, Object> data = dataList.getFirst();
                id = data.get("id").toString();
                branch = data.get("branch").toString();
                branchVersion = data.get("branch_version").toString();
            }

            String lastestBranch = Tool.isBlank(versionProperties.getBranch())
                    ? "master" : versionProperties.getBranch();
            String lastestVersion = Tool.isBlank(versionProperties.getBranchVersion())
                    ? "000000" : versionProperties.getBranchVersion();

            if (Tool.isBlank(branch)
                    || Tool.isBlank(branchVersion)
                    || !lastestBranch.equalsIgnoreCase(branch)
                    || !lastestVersion.equalsIgnoreCase(branchVersion)) {
                logger.info("版本不一致，当前版本：{} / {}，最新版本：{} / {}，初始化表结构...",
                        branch, branchVersion, lastestBranch, lastestVersion);
                initDatabase();
                logger.info("初始化表结构完成。");

                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("branch", lastestBranch);
                paramMap.put("branchVersion", lastestVersion);
                paramMap.put("updateTime", System.currentTimeMillis());

                if (Tool.isBlank(id)) {
                    paramMap.put("id", UUID.getUUID());
                    paramMap.put("sql", "insert into sys_version(id, branch, branch_version, update_time) " +
                            "values(#{id}, #{branch}, #{branchVersion}, #{updateTime})");
                    commonService.insert(paramMap, false);
                } else {
                    paramMap.put("id", id);
                    paramMap.put("sql", "update sys_version set " +
                            "branch=#{branch}, branch_version=#{branchVersion}, update_time=#{updateTime} " +
                            "where id=#{id}");
                    commonService.update(paramMap, false);
                }
            } else {
                logger.info("版本一致，当前版本：{} / {}，最新版本：{} / {}。",
                        branch, branchVersion, lastestBranch, lastestVersion);
            }
        } catch (Exception e) {
            logger.warn("数据库未初始化，进行数据库初始化操作...");

            // 初始化quartz表
            quartzRestoreService.restore(DatabaseUtil.getType());

            // 初始化表结构
            initDatabase();

            logger.info("数据库初始化完成。");
        }
    }

    private void initDatabase() throws Exception {
        ClassPathResource classPathResource = new ClassPathResource("system.dat");
        InputStream inputStream = classPathResource.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        BackupBO backup = backupRestoreService.restore(reader);
        inputStream.close();

        RestoreBO restore = new RestoreBO();
        restore.setName(backup.getName());
        restore.setType(backup.getType());
        restore.setMode(backup.getMode());
        restoreService.save(restore);
    }
}